import { AppDataSource } from '../config/db.js';
import { Entity, PrimaryGeneratedColumn, Column, Repository, Like, OneToMany } from 'typeorm';
import { Todo } from './todo.entity.js';

@Entity('users') // 指定数据库表名为 'users'
export class User {

  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  userName: string;

  @Column()
  password: string;

  @Column({ nullable: true }) // 新增字段，允许为空
  description: string;
  //token
  @Column({ nullable: true }) // 新增字段，允许为空
  token: string;
  @OneToMany(() => Todo, todo => todo.user)
  todos: Todo[];
  //生成一个token
  static generateToken() {
    return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
  }
  //根据id设置token
  static async setToken(id: number, token: string) {
    const userRepository = AppDataSource.getRepository(User);
    await userRepository.update(id, { token });
  }
  //根据token获取用户
  static async getUserByToken(token: string) {
    const userRepository = AppDataSource.getRepository(User);
    return await userRepository.findOneBy({ token });
  }

  static async createUser(user: Partial<User>): Promise<User> {
    const userRepository = AppDataSource.getRepository(User);
    return await userRepository.save(user);
  };

  static async findUserById(id: number): Promise<User | undefined> {
    const userRepository = AppDataSource.getRepository(User);
    return await userRepository.findOneBy({ id });
  };
  /**
   * 根据用户id获取todo数量信息
   * @param userId 用户id
   * @returns todo数量信息
   */
  static async getTodoCountByUserId(userId: number): Promise<{ total: number; completed: number }> {
    const todoRepository = AppDataSource.getRepository(Todo);
    const {total, completed} = await todoRepository.createQueryBuilder('todo')
      .select('COUNT(*)', 'total')
      .addSelect('SUM(CASE WHEN todo.completed = true THEN 1 ELSE 0 END)', 'completed')
      .where('todo.userId = :userId', { userId })
      .getRawOne();
    return { total: parseInt(total), completed: parseInt(completed) };
  }

  static async findUserByUserName(username: string): Promise<User | undefined> {
    const userRepository = AppDataSource.getRepository(User);
    return await userRepository.findOneBy({ userName: username });
  }

  static async updateUser(id: number, user: Partial<User>): Promise<User | undefined> {
    const userRepository = AppDataSource.getRepository(User);
    await userRepository.update(id, user);
    return await userRepository.findOneBy({ id });
  };

  static async deleteUser(id: number): Promise<void> {
    const userRepository = AppDataSource.getRepository(User);
    await userRepository.delete(id);
  };

  static async findUsersByUsernameWithPagination(page: number = 1, pageSize: number = 3, username = '') {
    const userRepository = AppDataSource.getRepository(User);
    const skip = (page - 1) * pageSize;
    let whereCondition = {};

    if (username) {
      whereCondition = { userName: Like(`%${username}%`) };
    }

    const [items, total] = await userRepository.findAndCount({
      where: whereCondition,
      skip,
      take: pageSize,
      order: {
        id: 'DESC' // 按 id 逆序排序
      }
    });

    const filteredItems = items.map(item => {
      const { password,token, ...rest } = item;
      return rest;
    });

    const pages = Math.ceil(total / pageSize);

    return {
      items: filteredItems,
      total,
      page,
      pageSize,
      pages
    };
  }
}


